Skip to main content

1. 判断当前目录是否为空功能开发

本周代码从commands/init/lib/index.js文件中的exec方法开始启动。 根据上面的两小节分析,exec方法的代码逻辑为:

  • 准备阶段 【this.prepare()】
  • 下载模版
  • 安装模版(下周实现)

prepare方法的代码逻辑为:

  1. 判断当前目录是否为空
  2. 是否强制清空
  3. 选择创建项目或组件
  4. 获取项目/组件的基本信息

本节主要实现的代码是判断当前目录是否为空

prepare() {
// 1. 判断当前目录是否为空
if (!this.isCwdEmpty()) {
// 1.1 询问是否继续创建
}
console.log(ret);
// 2. 是否启动强制更新
// 3. 选择创建项目或组件
// 4. 获取项目的基本信息
}
// 判断当前目录是否为空
isCwdEmpty() {
const localPath = process.cwd() // 当前工作目录
let fileList = fs.readdirSync(localPath)
fileList = fileList.filter(file => (
!file.startsWith('.') && ['node_modules'].indexOf(file) < 0
))
return !fileList || fileList.length <= 0
}

本节知识点:

  • 拿到当前目录的方法一:process.cwd()
  • 拿到当前目录的方法二: path.resolve('.')
  • path.resolve(__dirname):拿到的是当前执行代码的目录
  • 读取当前目录下的文件列表:fs.readdirSync()

2. 强制清空当前目录功能开发

本节主要是清空当前目录,进行清空下,使用命令行交互inquirer问询,以及用 force这个参数添加业务逻辑,进行目录的清空判断

清空目录功能主要是使用了第三方库*fs-extra**emptyDirSync***(localPath)**方法。

const inquirer = require('inquirer')
const fse = require('fs-extra')

// 1. 判断当前目录是否为空
const localPath = process.cwd() // 当前工作目录
if (!this.isDirEmpty(localPath)) {
let ifContinue = false
if (!this.force) {
// 询问是否继续创建
ifContinue = (await inquirer.prompt({
type: 'confirm',
name: 'ifContinue',
message: '当前文件夹不为空,是否继续创建项目?'
})).ifContinue
if (!ifContinue) {
return
}
}
// 2. 是否启动强制更新
if (ifContinue || this.force) {
// 给用户做二次确认
const { confirmDelete } = await inquirer.prompt({
type: 'confirm',
name: 'confirmDelete',
message: '是否确认清空当前目录下的文件?'
})
if (confirmDelete) {
// 清空当前目录
fse.emptyDirSync(localPath)
}
}

}

3. 获取项目基本信息功能开发

本节使用inquirer进行了项目或者组件的选择询问、以及版本号控制台输入功能,但未对输入内容进行校验 这里调整好代码逻辑即可。

async getProjectInfo() {
const projectInfo = {}
// 1. 选择创建项目或组件
const { type } = await inquirer.prompt({
type: 'list',
name: 'type',
message: '请选择初始化类型',
default: TYPE_PROJECT,
choices: [{
name: '项目',
value: TYPE_PROJECT
}, {
name: '组件',
value: TYPE_COMPONENT
}]
})
log.verbose('type', type)
// 2. 获取项目的基本信息
if (type === TYPE_PROJECT) {
const o = await inquirer.prompt([{
type: 'input',
name: 'projectName',
message: '请输入项目名称',
default: '',
validate: function (v) {
const done = this.async();

setTimeout(function () {
// 1. 输入的首字符必须为英文字母
// 2. 尾字符必须为英文或数字,不能为字符
// 3. 字符允许"-_"
// 合法: a, a-b, a_b, a-b-c, a-b1-c1,a_b1_c1a1,a1,a1-b1-c1, a1_b1_c1
// 不合法: 1,a_,a-.a_1,a-1
const reg = /^[a-zA-Z]+([-][a-zA-Z][a-zA-Z0-9]*|[_][a-zA-Z][a-zA-Z0-9]*|[a-zA-Z0-9])*$/
if (!reg.test(v)) {
done('请输入合法的项目名称');
return;
}
done(null, true);
}, 0);
},
filter: function (v) {
return v
}
}, {
type: 'input',
name: 'projectVersion',
message: '请输入项目版本号',
default: '1.0.0',
validate: function (v) {
const done = this.async();
setTimeout(function () {
if (!(!!semver.valid(v))) {
done('请输入合法的版本号');
return;
}
done(null, true);
}, 0);
},
filter: function (v) {
if (semver.valid(v)) {
return semver.valid(v)
} else {
return v
}
}
}])
console.log(o);
} else if (type === TYPE_COMPONENT) {

}
return projectInfo
}